package com.colabo.j2ee.web.core.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.colabo.j2ee.web.core.common.CommonConstants;
import com.colabo.j2ee.web.core.exception.CommonException;
import com.colabo.j2ee.web.core.exception.ReadableMessage;

/**
 * 提供了一些java reflect相关的功能,统一出错处理
 */
public class ReflectUtil {
	private static final Log LOGGER = LogFactory.getLog(ReflectUtil.class);

	/**
	 * 使用默认的构造器生成类的实例
	 * 
	 * @param clazz
	 *            类名称
	 * @return 类的实例
	 * @throws CommonException
	 */
	public static Object newInstance(String clazz) throws CommonException {
		try {
			return Class.forName(clazz).newInstance();
		} catch (InstantiationException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0004, new Object[] { clazz }),
					e);
		} catch (IllegalAccessException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0005, new Object[] { clazz }),
					e);
		} catch (ClassNotFoundException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0003, new Object[] { clazz }),
					e);
		}
	}

	/**
	 * 使用默认的构造器生成类的实例
	 */
	public static Object newInstance(Class clazz) throws CommonException {
		try {
			return clazz.newInstance();
		} catch (InstantiationException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0004, new Object[] { clazz }),
					e);
		} catch (IllegalAccessException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0005, new Object[] { clazz }),
					e);
		}
	}

	/**
	 * 根据类名称取得类
	 */
	public static Class forName(String clazzName) throws CommonException {
		try {
			return Class.forName(clazzName);
		} catch (ClassNotFoundException e) {
			throw new CommonException(new ReadableMessage(
					CommonConstants.MSG_ERR_BASE_0003,
					new Object[] { clazzName }), e);
		}
	}

	public static void setFieldValue(Object target, String fname, Class ftype,
			Object fvalue) {
		if (target == null
				|| fname == null
				|| "".equals(fname)
				|| (fvalue != null && !ftype
						.isAssignableFrom(fvalue.getClass()))) {
			return;
		}

		Class clazz = target.getClass();
		try {
			Method method = clazz.getDeclaredMethod(
					"set" + Character.toUpperCase(fname.charAt(0))
							+ fname.substring(1), new Class[] { ftype });
			if (!Modifier.isPublic(method.getModifiers())) {
				method.setAccessible(true);
			}
			method.invoke(target, new Object[] { fvalue });

		} catch (Exception me) {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug(me);
			}
			try {
				Field field = clazz.getDeclaredField(fname);
				if (!Modifier.isPublic(field.getModifiers())) {
					field.setAccessible(true);
				}
				field.set(target, fvalue);
			} catch (Exception fe) {
				if (LOGGER.isDebugEnabled()) {
					LOGGER.debug(fe);
				}
			}
		}
	}
}
